#include "NativeFieldProperty.h"

CNativeFieldProperty::CNativeFieldProperty(
    CPropertyList *InParentList
    , TMap<EPropertyFlags, SReflectionMetaDataValue> InMetaData
    , const SDecoratedType& InType
    , CString InName
    , uint64_t InOffset
    , uint32_t InFieldIndex
    )
    : CProperty(
        InParentList
        ,InName
        , InType
        , InMetaData
        )
{
    Offset = InOffset;
    FieldIndex = InFieldIndex;
    NonStaticProperty = new CNativeFieldGetSet(this);
    FieldProperty = new CNativeFieldGetPointer(this);
}

CNativeFieldGetSet::CNativeFieldGetSet(CNativeFieldProperty *InFieldProperty)
{
    FieldProperty = InFieldProperty;
}

CAny CNativeFieldGetSet::GetValue(const void *InObjectPtr)
{
    return CAny(FieldProperty->GetType().BasicType
    ,FieldProperty->GetType().BasicType->CloneInstance((void*)(reinterpret_cast<const uint8_t *>(InObjectPtr) + FieldProperty->GetNativeFieldOffset()))
    );
}

void CNativeFieldGetSet::SetValue(void *InObjectPtr, const CAny &InValue)
{
    // destroy the old value
    void * Memory = reinterpret_cast<uint8_t *>(InObjectPtr) + FieldProperty->GetNativeFieldOffset();
    FieldProperty->GetType().BasicType->EraseInstance(Memory);

    // copy the new value
    FieldProperty->GetType().BasicType->CloneInstance(
        InValue.GetPointer() 
        ,Memory);
}

CNativeFieldGetPointer::CNativeFieldGetPointer(CNativeFieldProperty *InFieldProperty)
{
    FieldProperty = InFieldProperty;
}

const void *CNativeFieldGetPointer::GetValuePointer(const void *InObjectPtr)
{
    return reinterpret_cast<const uint8_t *>(InObjectPtr) + FieldProperty->GetNativeFieldOffset();
}

void *CNativeFieldGetPointer::GetValuePointer(void *InObjectPtr)
{
    return reinterpret_cast<uint8_t *>(InObjectPtr) + FieldProperty->GetNativeFieldOffset();
}

uint32_t CNativeFieldGetPointer::GetFieldIndex()
{
    return FieldProperty->GetFieldIndex();
}
